package com.alipear.serverrequest;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.alipear.serverrequest.item.BaseResult;
import com.alipear.uibase.ExternActivityInterface;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.loopj.android.http.AsyncHttpResponseHandler;

import cz.msebera.android.httpclient.Header;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class DialogResponseHandler<E extends BaseResult> extends AsyncHttpResponseHandler {
	protected ExternActivityInterface mExternInterface;
	Gson mGson = new GsonBuilder().disableHtmlEscaping().create();;
	private String mErrMessage = null;
	private String mNormalServerErr = null;
    private E mResult;
	private String mCurUrl = null;
	private ProgressBar mProgressbar;
	private RequestProgressInterface mUserProgress = null;

    private long mRequestStartTime;

	public DialogResponseHandler(ExternActivityInterface externInterface, RequestProgressInterface userProgress) {
		init(externInterface, null);
		mUserProgress = userProgress;
	}

	public DialogResponseHandler(ExternActivityInterface externInterface) {
		init(externInterface, null);
	}

	public DialogResponseHandler(ExternActivityInterface externInterface, ProgressBar progressbar) {
		init(externInterface, progressbar);
	}

	private void init(ExternActivityInterface externInterface, ProgressBar progressbar) {
		mExternInterface = externInterface;
		mNormalServerErr = mExternInterface.getCurActivity().getString(R.string.server_error);
		mProgressbar = progressbar;
	}

	public void setCurUrl(String curUrl) {
		mCurUrl = curUrl;
	}

	/**
	 * Fired when the request is started, override to handle in your own code
	 */
	@Override
	public void onStart() {
        mRequestStartTime = System.currentTimeMillis();
		if (mUserProgress != null) {
			mUserProgress.onRequestStart();
		} else {
			showProgress();
		}
	}

	@Override
	public void onProgress(long bytesWritten, long totalSize)  {
		if (mUserProgress != null) {
			mUserProgress.onProgress(bytesWritten, totalSize);
		} else {
			super.onProgress(bytesWritten, totalSize);
		}
	}

	/**
	 * Fired in all cases when the request is finished, after both success and
	 * failure, override to handle in your own code
	 */
	@Override
	public void onFinish() {
        long duration  = System.currentTimeMillis() - mRequestStartTime;
        if (duration >= 500) {
            handleRequestFinished();
        }
        else {
            mExternInterface.getBaseHandler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    handleRequestFinished();
                }
            }, 500 - duration);
        }
	}

    private void handleRequestFinished() {
        if (mUserProgress != null) {
            mUserProgress.onRequestFinish();
        } else {
            hideProgress();
        }
        if (mErrMessage != null) {
            onRequestFailed(mErrMessage);
        }
        else {
            try {
                onRequestSuccess(mResult);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

	protected void showProgress() {
		if (mProgressbar != null) {
			mProgressbar.setVisibility(View.VISIBLE);
		} else {
			mExternInterface.showProgressDialog();
		}
	}

	protected void hideProgress() {
		if (mProgressbar != null) {
			mProgressbar.setVisibility(View.GONE);
		} else {
			mExternInterface.closeProgressDailog();
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
		String reason = new String(responseBody);
		Log.d("reason", reason);
		if (statusCode != 200) {
			mErrMessage = reason;
		} else {
			try {
				E result = createClassFromJson(reason);
				if (!result.isSuccess()) {
					mErrMessage = result.getError();
				} else {
                    mResult = result;
				}
			} catch (Exception e) {
				e.printStackTrace();
				mErrMessage = mNormalServerErr;
			}
		}
	}

	public abstract void onRequestSuccess(E result);

	public abstract void onRequestFailed(String errMessage);

	@Override
	public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
		if (mExternInterface instanceof Activity) {
			Toast.makeText((Context)mExternInterface, "您的网络状态不好哦！", Toast.LENGTH_SHORT).show();
		}
		if (responseBody != null) {
			String reason = new String(responseBody);
			System.out.println("reason" + reason);
			mErrMessage = reason;
			Log.d("DialogResponsHandler", "onFailure, err msg=" + mErrMessage);
		}
        else {
            mErrMessage = "服务器请求出错";
        }

		// Utility.showDialog(mExternInterface, , reason);
	}

	private E createClassFromJson(String jsonString) {
		// Type type = new TypeToken<classTmp.getName()>(){}.getType();
		return (E) mGson.fromJson(jsonString, getEType());
	}

	private Type getEType() {
		ParameterizedType pType = (ParameterizedType) this.getClass().getGenericSuperclass();
		Type[] types = pType.getActualTypeArguments();
		if (types.length > 1) {
			return types[1];
		} else {
			return types[0];
		}
	}
}
